﻿using System.Collections.Generic;
using CF.CFLog;
using CF.Core;
using UnityEngine;

namespace CF.Pool
{
    /// <summary>
    /// Pool Manager
    /// </summary>
    public class PoolManager : Singleton<PoolManager>
    {
        /// <summary>
        /// 默认对象池配置
        /// </summary>
        private PoolConfig defaultPoolConfig;

        /// <summary>
        /// 所有对象池
        /// </summary>
        private Dictionary<string, ObjectPool> pools;

        protected override void Awake()
        {
            base.Awake();
            defaultPoolConfig = new PoolConfig {MaxObjectCount = 500, IsClearOnSceneUnloaded = false};
            pools = new Dictionary<string, ObjectPool>();
        }

        protected override void OnDestroy()
        {
            base.OnDestroy();
            // DestroyAll ();
        }

        /// <summary>
        /// 创建一个默认配置对象池
        /// </summary>
        /// <param name="poolName"></param>
        /// <returns></returns>
        public ObjectPool CreateDefaultPool(string poolName)
        {
            return CreatePool(poolName, defaultPoolConfig);
        }

        /// <summary>
        /// 创建一个自定义配置的对象池
        /// </summary>
        /// <param name="poolName"></param>
        /// <param name="poolConfig"></param>
        /// <returns></returns>
        public ObjectPool CreatePool(string poolName, PoolConfig poolConfig)
        {
            if (pools.ContainsKey(poolName))
            {
                Log.Error($"Create Pool Failed. Pool had a pool named {poolName}.");
                return null;
            }

            var go = new GameObject(poolName);
            var pool = go.AddComponent<ObjectPool>();
            pool.transform.SetParent(transform);
            pool.Init(poolConfig);
            pools.Add(poolName, pool);
            return pool;
        }

        /// <summary>
        /// 根据名字获取对象池
        /// </summary>
        /// <param name="poolName"></param>
        /// <returns></returns>
        public ObjectPool GetObjectPool(string poolName)
        {
            return pools.TryGetValue(poolName, out ObjectPool pool) ? pool : null;
        }

        /// <summary>
        /// 清理某个对象池
        /// </summary>
        /// <param name="poolName"></param>
        public void ClearPool(string poolName)
        {
            if (pools.TryGetValue(poolName, out ObjectPool pool))
            {
                pool.ClearDespawnPool();
            }
        }

        /// <summary>
        /// 清理所有对象池
        /// </summary>
        public void ClearAll()
        {
            foreach (var pool in pools.Values)
            {
                pool.ClearDespawnPool();
            }

            // pools.Clear ();
        }

        /// <summary>
        /// 销毁指定对象池
        /// </summary>
        /// <param name="poolName"></param>
        public void DestroyPool(string poolName)
        {
            if (pools.TryGetValue(poolName, out ObjectPool pool))
            {
                pool.Destroy();
            }
        }

        /// <summary>
        /// 销毁所有对象池
        /// </summary>
        public void DestroyAll()
        {
            foreach (var pool in pools.Values)
            {
                pool.Destroy();
            }

            pools.Clear();
        }
    }
}